package com.miniserver.wx.utils;

import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.UUID;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

import com.miniserver.util.cache.MemCacheManager;

public class WxUtil {
	private static final String CACHE_ACCESS_TOKEN = "CACHE_ACCESS_TOKEN";
	private static final String CACHE_JS_TOKEN = "CACHE_JS_TOKEN";
	
	/**
	 * 根据appId和appSecret获取accessToken
	 * @param appId
	 * @param appSecret
	 * @return
	 */
	public static String generateAccessToken(String appId, String appSecret) {
		String accessToken = MemCacheManager.getValue(CACHE_ACCESS_TOKEN, appId);
		if(StringUtils.isBlank(accessToken)) {
			try {
				String result = HttpHelper.get(String.format(WxConstants.ACCESS_TOKEN_URL, appId, appSecret), true);
				
				JSONObject resultObj = JSONObject.fromObject(result);
				if(resultObj.containsKey("access_token")){
					accessToken = resultObj.getString("access_token");
					Long expires = resultObj.optLong("expires_in", 3600l);
					
					// 处理缓存
					HashMap<String,String> valueMap = new HashMap<String,String>();
					valueMap.put(appId, accessToken);
					MemCacheManager.put(CACHE_ACCESS_TOKEN, valueMap, expires);
				}
			} catch (Exception e) {
				System.out.println("获取access_token失败。appid:" + appId + "; appsecret:" + appSecret);
				e.printStackTrace();
			}
		}
		
		return accessToken;
	}

	/**
	 * 获取jsapi签名信息
	 * @param appId
	 * @param appSecret
	 * @param url
	 * @return
	 */
	public static JSONObject generateJsapiTicket(String appId, String appSecret, String url) {
		JSONObject result = new JSONObject();
		
		String jsapiTicket = MemCacheManager.getValue(CACHE_JS_TOKEN, appId);
		try {
			if(StringUtils.isBlank(jsapiTicket)) {
				String accessToken = generateAccessToken(appId, appSecret);
				// 重新获取jsapi
				String resp = HttpHelper.get(String.format(WxConstants.JSAPI_TICKET_URL, accessToken), true);
				JSONObject respObj = JSONObject.fromObject(resp);
				if(respObj.optInt("errcode") == 0 && respObj.containsKey("ticket")) {
					jsapiTicket = respObj.getString("ticket");
					Long expires = respObj.optLong("expires_in", 3600l);
					
					// 处理缓存
					HashMap<String,String> valueMap = new HashMap<String,String>();
					valueMap.put(appId, jsapiTicket);
					MemCacheManager.put(CACHE_JS_TOKEN, valueMap, expires);
				}
			}
			
			String noncestr = createNoncestr();
			String timestamp = createTimestamp();
			String orginalStr = 
					"jsapi_ticket=" + jsapiTicket +
					"&noncestr=" + noncestr +
					"&timestamp=" + timestamp +
					"&url=" + url;
			
	        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
	        crypt.reset();
	        crypt.update(orginalStr.getBytes("UTF-8"));
	        String signature = byteToHex(crypt.digest());
	        
	        result.put("appid", appId);
	        result.put("jsapiticket", jsapiTicket);
	        result.put("noncestr", noncestr);
	        result.put("timestamp", timestamp);
	        result.put("url", url);
	        result.put("signature", signature);
			result.put("success", true);
		} catch (Exception e) {
			e.printStackTrace();
			result.put("success", false);
		}
		
		return result;
			
//			Cache cache = MemCacheManager.getCache(CACHE_JS_TOKEN + appId);
//			// 从缓存中获取签名数据
//			if(cache != null && accessToken.equals( cache.getValue().get("accesstoken")) && url.equals(cache.getValue().get("url"))){
//				result = JSONObject.fromObject(cache.getValue());
//				result.put("success", true);
//			} else {
//				// 重新获取jspapi_ticket
//				try {
//					String resp = HttpHelper.get(String.format(WxConstants.JSAPI_TICKET_URL, accessToken), true);
//					JSONObject respObj = JSONObject.fromObject(resp);
//					if(respObj.optInt("errcode") == 0 && respObj.containsKey("ticket")) {
//						String noncestr = createNoncestr();
//						String timestamp = createTimestamp();
//						String ticket = respObj.getString("ticket");
//						String orginalStr = 
//								"jsapi_ticket=" + ticket +
//								"&noncestr=" + noncestr +
//								"&timestamp=" + timestamp +
//								"&url=" + url;
//						
//			            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
//			            crypt.reset();
//			            crypt.update(orginalStr.getBytes("UTF-8"));
//			            String signature = byteToHex(crypt.digest());
//			            
//			            HashMap<String, String> map = new HashMap<String,String>();
//			            map.put("appid", appId);
//			            map.put("accesstoken", accessToken);
//			            map.put("jsapiticket", ticket);
//			            map.put("noncestr", noncestr);
//			            map.put("timestamp", timestamp);
//			            map.put("url", url);
//			            map.put("signature", signature);
//			            
//			            result = JSONObject.fromObject(map);
//			            // 放入缓存
//			            MemCacheManager.put(CACHE_JS_TOKEN + appId, map, respObj.optLong("expires_in", 7200l));
//			            result.put("success", true);
//					} else {
//						result.put("success", false);
//					}
//				} catch (Exception e) {
//					result.put("success", false);
//					e.printStackTrace();
//				}
//			}
//		} else {
//			result.put("success", false);
//		}
	}
	
	private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String createNoncestr() {
        return UUID.randomUUID().toString();
    }

    private static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
	
	
	public static void main(String[] args) {
//		System.out.println(generateAccessToken("wx6a69ee1488e43154", "27bff54f6db800889eb03854bf96cca1"));
	}
}